package com.syezon.wifikey.splash.self;

import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.blankj.utilcode.util.AppUtils;
import com.hodanet.appadvplatclient.ReportAgent;
import com.hodanet.appadvplatclient.ad.AdInfo;
import com.syezon.wifikey.R;
import com.syezon.wifikey.ad.AdPositionEnum;
import com.syezon.wifikey.ad.AdUtils;
import com.syezon.wifikey.ad.SplashAdViewModel;
import com.syezon.wifikey.channel.ChannelConfig;
import com.syezon.wifikey.imageloader.ImageLoader;
import com.syezon.wifikey.splash.SplashCallBack;
import com.syezon.wifikey.splash.config.SplashConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import butterknife.BindView;
import butterknife.ButterKnife;

public class SelfSplashFragment extends Fragment implements SelfSplashAdListener {

    private static final String TAG = SelfSplashFragment.class.getSimpleName();

    private static final int SPLASH_TIME = 3;
    private static final int SPLASH_AD_TIME = 4;
    private static int minSplashTimeWhenNoAD = 2000;

    private static final int MSG_SPLASH_DOWN_COUNT = 1;

    private static final String SKIP_TEXT = "点击跳过 %d";

    public boolean canJump = false;

    private int times = SPLASH_TIME;

    /**
     * 为防止无广告时造成视觉上类似于"闪退"的情况，设定无广告时页面跳转根据需要延迟一定时间，demo
     * 给出的延时逻辑是从拉取广告开始算开屏最少持续多久，仅供参考，开发者可自定义延时逻辑，如果开发者采用demo
     * 中给出的延时逻辑，也建议开发者考虑自定义minSplashTimeWhenNoAD的值（单位ms）
     **/
    /**
     * 记录拉取广告的时间
     */
    private long fetchSplashADTime = 0;
    private Handler handler = new Handler(Looper.getMainLooper());

    @BindView(R.id.view_logo_bottom)
    View mViewBottom;
    @BindView(R.id.img_logo)
    ImageView mImgLogo;
    @BindView(R.id.tv_skip)
    TextView mSkipView;

    private List<AdInfo> mAdInfos = new ArrayList<>();
    private SplashCallBack mListener;

    private SplashAdViewModel mSplashAdViewModel;

    private Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SPLASH_DOWN_COUNT:
                    mSkipView.setText(String.format(SKIP_TEXT, times));
                    if (times <= 0) {
                        mHandler.removeMessages(MSG_SPLASH_DOWN_COUNT);
                        if (mAdInfos.isEmpty()) {
                            onNoAD();
                        } else {
                            next();
                        }
                        return;
                    } else {
                        times--;
                        mHandler.sendEmptyMessageDelayed(MSG_SPLASH_DOWN_COUNT, 1000);
                    }
                    break;
            }

        }
    };

    public SelfSplashFragment() {
    }

    public static SelfSplashFragment newInstance() {
        SelfSplashFragment fragment = new SelfSplashFragment();
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.app_splash_fragment_self, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.bind(this, view);
        init();
    }

    private void init() {
        mHandler.sendEmptyMessage(MSG_SPLASH_DOWN_COUNT);
        mSkipView.setVisibility(View.INVISIBLE);
        getAdData();
    }

    public void getAdData() {
        fetchSplashADTime = System.currentTimeMillis();
        mSplashAdViewModel = ViewModelProviders.of(this).get(SplashAdViewModel.KEY_PREFIX + AdPositionEnum.SPLASH.getUmengEventId(), SplashAdViewModel.class);
        mSplashAdViewModel.setAdPositionEnum(AdPositionEnum.SPLASH);
        mSplashAdViewModel.getAdLiveData().observe(this, new Observer<List<AdInfo>>() {
            @Override
            public void onChanged(@Nullable List<AdInfo> adInfos) {
                mAdInfos.clear();
                if (adInfos != null && adInfos.size() > 0) {
                    mAdInfos.addAll(adInfos);
                }
                showAdView();
            }
        });
    }

    private void showAdView() {
        if (mAdInfos.size() > 0) {
            Random random = new Random();
            final AdInfo adInfo = mAdInfos.get(random.nextInt(mAdInfos.size()));
            if (adInfo != null && adInfo.getUrl() != null) {
                mHandler.removeCallbacksAndMessages(null);
                times = SPLASH_AD_TIME;
                mHandler.sendEmptyMessage(MSG_SPLASH_DOWN_COUNT);
                onADPresent();
                ImageLoader.getInstance().displayImage(this, adInfo.getPic(), mImgLogo);
                ReportAgent.reportAdvExtShow(adInfo, ChannelConfig.getChannel(), AppUtils.getAppVersionCode());
                mImgLogo.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        AdUtils.adClicked(getContext(), adInfo, AdPositionEnum.SPLASH);
                    }
                });
            }
        } else {
            mHandler.removeCallbacksAndMessages(null);
            onNoAD();
        }
    }


    @Override
    public void onADPresent() {
        mSkipView.setVisibility(View.VISIBLE);
        mSkipView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onADDismissed();
            }
        });
        if (mListener != null) {
            mListener.onLoadSuccess(SplashConfig.SPLASH_AD_SOURCE_SELF);
        }
    }

    @Override
    public void onADClicked() {
    }

    /**
     * 倒计时回调，返回广告还将被展示的剩余时间。
     * 通过这个接口，开发者可以自行决定是否显示倒计时提示，或者还剩几秒的时候显示倒计时
     *
     * @param millisUntilFinished 剩余毫秒数
     */
    @Override
    public void onADTick(long millisUntilFinished) {
        mSkipView.setText(String.format(SKIP_TEXT, Math.round(millisUntilFinished / 1000f)));
    }

    @Override
    public void onADExposure() {
    }

    @Override
    public void onADDismissed() {
        next();
    }

    @Override
    public void onNoAD() {
        if (mListener != null) {
            mListener.onLoadFail(SplashConfig.SPLASH_AD_SOURCE_SELF, "没有广告");
            return;
        }
        /**
         * 为防止无广告时造成视觉上类似于"闪退"的情况，设定无广告时页面跳转根据需要延迟一定时间，demo
         * 给出的延时逻辑是从拉取广告开始算开屏最少持续多久，仅供参考，开发者可自定义延时逻辑，如果开发者采用demo
         * 中给出的延时逻辑，也建议开发者考虑自定义minSplashTimeWhenNoAD的值
         **/
        long alreadyDelayMills = System.currentTimeMillis() - fetchSplashADTime;//从拉广告开始到onNoAD已经消耗了多少时间
        long shouldDelayMills = alreadyDelayMills > minSplashTimeWhenNoAD ? 0 : minSplashTimeWhenNoAD
                - alreadyDelayMills;//为防止加载广告失败后立刻跳离开屏可能造成的视觉上类似于"闪退"的情况，根据设置的minSplashTimeWhenNoAD
        // 计算出还需要延时多久
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (mListener != null) {
                    mListener.goMain();
                }
            }
        }, shouldDelayMills);
    }

    /**
     * 设置一个变量来控制当前开屏页面是否可以跳转，当开屏广告为普链类广告时，点击会打开一个广告落地页，此时开发者还不能打开自己的App主页。当从广告落地页返回以后，
     * 才可以跳转到开发者自己的App主页；当开屏广告是App类广告时只会下载App。
     */

    private void next() {
        if (canJump) {
            if (mListener != null) {
                mListener.goMain();
            }
        } else {
            canJump = true;
        }

    }

    @Override
    public void onPause() {
        super.onPause();
        canJump = false;
    }

    @Override
    public void onResume() {
        super.onResume();
        if (canJump) {
            next();
        }
        canJump = true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        try {
            handler.removeCallbacksAndMessages(null);
            mHandler.removeCallbacksAndMessages(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof SplashCallBack) {
            mListener = (SplashCallBack) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement SplashCallBack");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

}
